﻿namespace TeF
{
    /// <summary>Asserts that can be used to check result of the test</summary>
    public static class Assert
    {
        /// <summary>Checks that <see cref="actual"/> is equal to <see cref="expected"/></summary>
        /// <exception cref="AssertException">If <see cref="actual"/> is not equal to <see cref="expected"/></exception>
        public static void AreEqual(object expected, object actual)
        {
            if (!Equals(expected, actual))
                throw new AssertException(
                    "Assertion failed. Expected '{0}' and actual '{1}' are not equal.",
                    expected ?? "null", actual ?? "null");
        }

        /// <summary>Checks that <see cref="actual"/> is not equal to <see cref="notExpected"/></summary>
        /// <exception cref="AssertException">If <see cref="actual"/> is equal to <see cref="notExpected"/></exception>
        public static void AreNotEqual(object notExpected, object actual)
        {
            if (Equals(notExpected, actual))
                throw new AssertException(
                    "Assertion failed. Not expected '{0}' and actual '{1}' are equal.",
                    notExpected ?? "null", actual ?? "null");
        }

        /// <summary>Checks whether <see cref="value"/> is null</summary>
        /// <exception cref="AssertException">If <see cref="value"/> is not null</exception>
        public static void IsNull(object value)
        {
            if (value != null)
                throw new AssertException("Assertion failed. Value '{0}' is not null.", value);
        }

        /// <summary>Checks whether <see cref="value"/> is not null</summary>
        /// <exception cref="AssertException">If <see cref="value"/> is null</exception>
        public static void IsNotNull(object value)
        {
            if (value == null)
                throw new AssertException("Assertion failed. Value is null.");
        }

        /// <summary>Checks that <see cref="actual"/> is pointed to the same object as <see cref="expected"/></summary>
        /// <exception cref="AssertException">If <see cref="actual"/> is pointed to another object then <see cref="expected"/></exception>
        public static void AreSame(object expected, object actual)
        {
            if (!ReferenceEquals(expected, actual))
                throw new AssertException(
                    "Assertion failed. Expected '{0}' and actual '{1}' are not same.",
                    expected ?? "null", actual ?? "null");
        }

        /// <summary>Checks that <see cref="actual"/> is not pointed to the same object as <see cref="notExpected"/></summary>
        /// <exception cref="AssertException">If <see cref="actual"/> is pointed to the same object as <see cref="notExpected"/></exception>
        public static void AreNotSame(object notExpected, object actual)
        {
            if (ReferenceEquals(notExpected, actual))
                throw new AssertException(
                    "Assertion failed. Not expected '{0}' and actual '{1}' are same.",
                    notExpected ?? "null", actual ?? "null");
        }
    }
}
